This is a brief comparison of definitions for “middle neighborhoods” in Baltimore. The two definitions being compared are:
U.S. Census data being used are the 2012-2016 (5-year) American Community Survey estimates.
Are there any other definitions we should consider?
# neighborhood boundaries
hoods.url <- "https://data.baltimorecity.gov/resource/h3fx-54q3.geojson"
# surely there is a better way, and i tried, but couldn't get anything else to work.
# from geojson to sf to spatial df. geojson_sp didn't work for me.
hoods <- geojson_sf(hoods.url)
incomplete final line found on 'https://data.baltimorecity.gov/resource/h3fx-54q3.geojson'
hoods <- as_Spatial(hoods)
hoods <- spTransform(hoods, CRS("+init=epsg:4326"))
# HUD area median income for Baltimore-Columbia-Towson
ami.2016 <- 86700
#ami.2018 <- 94900
hmt@data <- hmt@data %>% mutate(
# assign healthy, middle, and distressed based on HMT
hmt.tier = case_when(
MVA17HrdCd %in% c("A", "B", "C") ~ "healthy",
MVA17HrdCd %in% c("D", "E", "F", "G", "H") ~ "middle",
MVA17HrdCd %in% c("I", "J") ~ "distressed",
TRUE ~ "other"),
# HMT again, but with middle broken in two
hmt.tier.2mid = case_when(
MVA17HrdCd %in% c("A", "B", "C") ~ "healthy",
MVA17HrdCd %in% c("D", "E") ~ "upper middle",
MVA17HrdCd %in% c("F", "G", "H") ~ "lower middle",
MVA17HrdCd %in% c("I", "J") ~ "distressed",
TRUE ~ "other"),
# assign healthy, middle, and distressed based on block group median income
med.inc.tier =
case_when(
(hmt.tier != "other") &
(Median_Household_Income.2016 > 1.25 * ami.2016) ~ "healthy",
(hmt.tier != "other") &
(Median_Household_Income.2016 < 0.75 * ami.2016) ~ "distressed",
(hmt.tier == "other") ~ NA_character_,
TRUE ~ "middle"
)
)
This map shows only middle neighborhoods based on HMT (includes only typologies D through H). Black borders and labels-on-hover are for neighborhoods. At first glance, this removes neighborhoods within the “white L” and “black butterfly” neighborhoods of Baltimore, with most everything else remaining.
mid.hoods.hmt <- subset(hmt, hmt.tier == "middle")
leaflet() %>%
setView(lng = -76.6, lat = 39.3, zoom = 11) %>%
addProviderTiles(providers$Stamen.TonerLite) %>%
addPolygons(data = mid.hoods.hmt,
color = iteam.colors[1],
weight = 1,
#fillColor = ~pal(MVA17HrdCd),
fillColor = iteam.colors[1],
fillOpacity = .6,
#opacity = 0,
label = ~as.character(mid.hoods.hmt$MVA17HrdCd)
) %>%
#addGeoJSON(hoods, weight = 1, color = "black", fillOpacity = 0)
addPolygons(data = hoods,
weight = 2,
color = "black",
opacity = 0.5,
fillOpacity = 0,
label = ~hoods$label)
Breaking “middle” into “lower middle” (F, G, H) and “upper middle” (D, E) and including “healthy” and "distressed:
#mid.hoods.hmt.2mid <- subset(hmt, hmt.tier.2mid %in% c("lower middle", "upper middle"))
hmt.2mid.pal <- colorFactor(
domain = hmt$hmt.tier.2mid,
palette = c(iteam.colors[4],
iteam.colors[3],
"#f4d57f",
NA,
iteam.colors[1])
)
leaflet() %>%
setView(lng = -76.6, lat = 39.3, zoom = 11) %>%
addProviderTiles(providers$Stamen.TonerLite) %>%
addPolygons(data = hmt,
color = iteam.colors[1],
weight = 1,
fillColor = ~hmt.2mid.pal(hmt.tier.2mid),
#fillColor = iteam.colors[1],
fillOpacity = .6,
#opacity = 0,
label = ~as.character(hmt$MVA17HrdCd)
) %>%
#addGeoJSON(hoods, weight = 1, color = "black", fillOpacity = 0)
addPolygons(data = hoods,
weight = 2,
color = "black",
opacity = 0.5,
fillOpacity = 0,
label = ~hoods$label)
This map shows only middle neighborhoods based on the median income definition - that is, block groups where the household median income is between 75% and 125% of the area median income (Baltimore-Columbia-Towson for 2016). Qualitatively, this results in a more sparse and disjointed definition of middle neighborhoods.
mid.hoods.med.inc <- subset(hmt, med.inc.tier == "middle")
leaflet() %>%
setView(lng = -76.6, lat = 39.3, zoom = 11) %>%
addProviderTiles(providers$Stamen.TonerLite) %>%
addPolygons(data = mid.hoods.med.inc,
color = iteam.colors[3],
weight = 1,
#fillColor = ~pal(MVA17HrdCd),
fillColor = iteam.colors[3],
fillOpacity = .6,
#opacity = 0,
label = ~as.character(mid.hoods.med.inc$MVA17HrdCd)
) %>%
#addGeoJSON(hoods, weight = 1, color = "black", fillOpacity = 0)
addPolygons(data = hoods,
weight = 2,
color = "black",
opacity = 0.5,
fillOpacity = 0,
label = ~hoods$label)
The map below overlays the two definitions.
leaflet() %>%
setView(lng = -76.6, lat = 39.3, zoom = 11) %>%
addProviderTiles(providers$Stamen.TonerLite) %>%
addPolygons(data = mid.hoods.med.inc,
color = iteam.colors[3],
weight = 1,
#fillColor = ~pal(MVA17HrdCd),
fillColor = iteam.colors[3],
fillOpacity = .7,
#opacity = 0,
label = ~as.character(mid.hoods.med.inc$MVA17HrdCd)) %>%
addPolygons(data = mid.hoods.hmt,
color = iteam.colors[1],
weight = 1,
#fillColor = ~pal(MVA17HrdCd),
fillColor = iteam.colors[1],
fillOpacity = .5,
#opacity = 0,
label = ~as.character(mid.hoods.hmt$MVA17HrdCd)) %>%
addPolygons(data = hoods,
weight = 2,
color = "black",
opacity = 0.5,
fillOpacity = 0,
label = ~hoods$label) %>%
addLegend("bottomright",
colors = c(iteam.colors[1], iteam.colors[3]),
labels = c("HMT", "Median Income"))